/**
 * Copyright (C)  Gadglet .
 *
 * This file is part of Gadglet
 *
 * Gadglet is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Gadglet is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with Gadglet. If not, see <http://www.gnu.org/licenses/>.
 */

package com.gadglet.client.gwt.core;


import java.util.HashMap;
import java.util.Map;

import com.gadglet.client.gwt.ui.DebugDialogBox;
import com.gadglet.params.ResParamNames;
import com.gadglet.params.ResStatus;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.JsArray;
import com.google.gwt.json.client.JSONArray;
import com.google.gwt.json.client.JSONObject;

/**
 *         Provides client object to process results from the server. The Object
 *         is created by the class GadgletRequest
 */

public class GadgletResponse {

	private JSONObject responseHeader = null;
	private JSONArray responseBodyItems = null;
	final protected DebugDialogBox errorNotifier = DebugDialogBox
			.getErrorNotifier();

	public GadgletResponse(JsArray<JavaScriptObject> res) {

		try {
			responseHeader = (new JSONObject(res))
					.get(ResParamNames.RES_NAME.getParamName()).isObject()
					.get(ResParamNames.RES_HEADR.getParamName()).isObject();
			responseBodyItems = (new JSONObject(res))
					.get(ResParamNames.RES_NAME.getParamName()).isObject()
					.get(ResParamNames.RES_ITEMS.getParamName()).isArray();
			;
		} catch (Exception e) {
			errorNotifier.showError(13, "faile to get message");
		}
	}

	/**
	 * @return JSONObject representing the Header of the server response
	 */
	public JSONObject getResponseHeader() {
		return this.responseHeader;
	}
	
	/**
	 * @return JSONArray representing the results
	 */
	public JSONArray getResponseBodyItems() {
		return this.responseBodyItems;
	}

	public String getError() {
		String error = "";
		try {
			if (responseHeader.isObject().get(
					ResParamNames.RES_ERROR_MSG.getParamName()) != null)
				error = responseHeader.isObject()
						.get(ResParamNames.RES_ERROR_MSG.getParamName())
						.isString().stringValue();

		} catch (Exception e) {
			errorNotifier.showError(14,e.getMessage());
		}

		return error;

	}

	/**
	 * @return the request status: OK/ERROR
	 */
	public String getStatus() {
		String status = ResStatus.ERROR.getStatus();
		try {
			status = responseHeader.isObject()
					.get(ResParamNames.RES_STATUS.getParamName()).isString()
					.stringValue();
		} catch (Exception e) {
			errorNotifier.showError(15, e.getMessage());
		}
		return status;

	}
	
	
	/**
	 * @return user is permitted to add content item
	 */
	public boolean isAddPermitted() {
		boolean isPermitted = false;
		try {
			if(responseHeader.isObject()
					.get(ResParamNames.RES_ADD_ITEMS_PERMIT.getParamName())!=null)
			 isPermitted = responseHeader.isObject()
					.get(ResParamNames.RES_ADD_ITEMS_PERMIT.getParamName()).isBoolean().booleanValue();
			
		} catch (Exception e) {
			errorNotifier.showError(16, e.getMessage());
		}
		
	return 	isPermitted;

	}

	
	/**
	 * @return true - the request was successful, false - error
	 */
	public boolean isSuccessful() {

		if (getStatus().equals(ResStatus.OK.getStatus()))
			return true;
		else
			return false;
	}

	public String getVersion() {
		String version = null;
		try {
			version = responseHeader.isObject()
					.get(ResParamNames.RES_VERSION.getParamName()).isString()
					.stringValue();
		} catch (Exception e) {
			errorNotifier.showError(15, e.getMessage());
		}
		return version;
	}

	
	/**
	 * @return true - there are more items to show and a "next" button ay be shown
	 */
	public boolean hasMoreItems() {

		boolean hasnore = false;
		try {
			hasnore = responseHeader.isObject()
					.get(ResParamNames.RES_HAS_MORE_ITEMS.getParamName())
					.isBoolean().booleanValue();
		} catch (Exception e) {
			errorNotifier.showError(17, e.getMessage());
		}
		return hasnore;

	}

	
	/**
	 * @return Map of fields level errors
	 */
	public Map<String, String> getFieldsErrors() {
		JSONArray jsonFieldsErrors = null;
		Map<String, String> fieldsErrors = new HashMap<String, String>();

		try {
			jsonFieldsErrors = responseHeader.isObject()
					.get(ResParamNames.RES_FIELDS_ERRORS.getParamName())
					.isArray();
		} catch (Exception e) {
			errorNotifier.showError(18, e.getMessage());
		}

		String fieldName = null;
		String fieldMsg = null;

		if (jsonFieldsErrors != null)

			for (int index = 0; index < jsonFieldsErrors.size(); index++) {

				try {
					fieldName = jsonFieldsErrors
							.get(index)
							.isObject()
							.get(ResParamNames.RES_FIELD_ERROR.getParamName())
							.isObject()
							.get(ResParamNames.RES_ERROR_FIELD_NAME
									.getParamName()).isString().stringValue();

					fieldMsg = jsonFieldsErrors
							.get(index)
							.isObject()
							.get(ResParamNames.RES_FIELD_ERROR.getParamName())
							.isObject()
							.get(ResParamNames.RES_FIELD_ERROR_MSG
									.getParamName()).isString().stringValue();

					fieldsErrors.put(fieldName, fieldMsg);
				} catch (Exception e) {
					errorNotifier.showError(19, e.getMessage());
				}

				fieldName = null;
				fieldMsg = null;
			}
		return fieldsErrors;
	}

	
	
	/**
	 * @return - Map of Gadget headers
	 */
	public Map<String, String> getCustomHeaders() {
		JSONArray jsonCustomHeaders = null;
		Map<String, String> customHeaders = new HashMap<String, String>();

		try {
			jsonCustomHeaders = responseHeader.isObject()
					.get(ResParamNames.RES_CUSTOM_HEADERS.getParamName())
					.isArray();
		} catch (Exception e) {
			errorNotifier.showError(20, e.getMessage());
		}

		String fieldName = null;
		String fieldMsg = null;

		if (jsonCustomHeaders != null)

			for (int index = 0; index < jsonCustomHeaders.size(); index++) {

				try {
					fieldName = jsonCustomHeaders
							.get(index)
							.isObject()
							.get(ResParamNames.RES_CUSTOM_HEADER_FIELD
									.getParamName())
							.isObject()
							.get(ResParamNames.RES_CUSTOM_HEADER_NAME
									.getParamName()).isString().stringValue();

					fieldMsg = jsonCustomHeaders
							.get(index)
							.isObject()
							.get(ResParamNames.RES_CUSTOM_HEADER_FIELD
									.getParamName())
							.isObject()
							.get(ResParamNames.RES_CUSTOM_HEADER_VALUE
									.getParamName()).isString().stringValue();

					customHeaders.put(fieldName, fieldMsg);
				} catch (Exception e) {
					errorNotifier.showError(21, e.getMessage());
				}

				fieldName = null;
				fieldMsg = null;
			}
		return customHeaders;
	}

	public int getRootItemsNum() {

		int num = 0;

		if (responseBodyItems != null)
			num = responseBodyItems.size();

		return num;
	}

	
	
	/**
	 * @param fieldName - name of field in the response
	 * @param index - item index in the response
	 * @return - value
	 */
	public String getStringItemValue(String fieldName, int index) {

		String value = "";
		if (fieldName == null)
			return value;
		try {
			if(responseBodyItems.get(index).isObject()!=null)
				if(responseBodyItems.get(index).isObject().get(ResParamNames.RES_SINGLE_ITEM.getParamName())!=null)
					if(responseBodyItems.get(index).isObject().get(ResParamNames.RES_SINGLE_ITEM.getParamName()).isObject()
							.get(fieldName)!=null)
			value = responseBodyItems.get(index).isObject()
					.get(ResParamNames.RES_SINGLE_ITEM.getParamName())
					.isObject().get(fieldName).isString().stringValue();
		} catch (Exception e) {
			errorNotifier.showError(22, e.getMessage());
		}

		return value;

	}

	
	
	/**
	 * @param index - item index in the response
	 * @return - JSONObject 
	 */
	public JSONObject getItem(int index) {
		
	JSONObject item = null;
		
		try {
			if(responseBodyItems.get(index)!=null)
			item =   responseBodyItems.get(index).isObject()
					.get(ResParamNames.RES_SINGLE_ITEM.getParamName())
					.isObject();
		} catch (Exception e) {
			errorNotifier.showError(23,  e.getMessage());
		}
		
		return item;
	}


	

	/**
	 * @param index  - item index in the response
	 * @return get the item key field
	 */
	public String getItemKeyValue(int index) {

		String value = "";

		try {
			if(responseBodyItems.get(index)!=null)
				if(responseBodyItems.get(index).isObject()
					.get(ResParamNames.RES_SINGLE_ITEM.getParamName())!=null)
					if(responseBodyItems.get(index).isObject()
							.get(ResParamNames.RES_SINGLE_ITEM.getParamName())
							.isObject()
							.get(ResParamNames.RES_ITEM_KEY_PARAM_NAME.getParamName())!=null)
							value = responseBodyItems.get(index).isObject()
						.get(ResParamNames.RES_SINGLE_ITEM.getParamName())
						.isObject()
						.get(ResParamNames.RES_ITEM_KEY_PARAM_NAME.getParamName())
						.isString().stringValue();
		} catch (Exception e) {
			errorNotifier.showError(24, e.getMessage());
		}

		return value;

	}
	

	/**
	 * @param index - item index in the response
	 * @return true - user is allowed to delete this item
	 */
	public  boolean isDeletePermitted(int index){
		boolean isPermited  = false;
		try {
			if(responseBodyItems.get(index).isObject()!=null)
				if(responseBodyItems.get(index).isObject().get(ResParamNames.RES_ITEM_PERMISSINS.getParamName())!=null)
					if(responseBodyItems.get(index).isObject().get(ResParamNames.RES_ITEM_PERMISSINS.getParamName()).isObject().get(ResParamNames.RES_ITEM_DELETE_PERMIT.getParamName())!=null)
						isPermited = responseBodyItems.get(index).isObject().get(ResParamNames.RES_ITEM_PERMISSINS.getParamName()).isObject().get(ResParamNames.RES_ITEM_DELETE_PERMIT.getParamName()).isBoolean().booleanValue();
		} catch (Exception e) {
			errorNotifier.showError(25,e.getMessage());

		}
	
		return isPermited;
	}
	
	/**
	 * @param index - item index in the response
	 * @return true - user is allowed to update this item
	 */
	public  boolean isUpdatePermitted(int index){
			
		boolean isPermited  = false;
		try {
			if(responseBodyItems.get(index).isObject().get(ResParamNames.RES_ITEM_PERMISSINS.getParamName())!=null)
				if(responseBodyItems.get(index).isObject().get(ResParamNames.RES_ITEM_PERMISSINS.getParamName()).isObject().get(ResParamNames.RES_ITEM_UPDATE_PERMIT.getParamName())!=null)
					isPermited = responseBodyItems.get(index).isObject().get(ResParamNames.RES_ITEM_PERMISSINS.getParamName()).isObject().get(ResParamNames.RES_ITEM_UPDATE_PERMIT.getParamName()).isBoolean().booleanValue();
		} catch (Exception e) {
			errorNotifier.showError(26, e.getMessage());

		}
	
		return isPermited;
	}
	
	
	/**
	 * @param index - item index in the response
	 * @return true - user is allowed to share this item
	 */
	
	public  boolean isSharePermitted(int index){
		boolean isPermited  = false;
		try {
			if(responseBodyItems.get(index).isObject().get(ResParamNames.RES_ITEM_PERMISSINS.getParamName())!=null)
				if(responseBodyItems.get(index).isObject().get(ResParamNames.RES_ITEM_PERMISSINS.getParamName()).isObject().get(ResParamNames.RES_ITEM_SHARE_PERMIT.getParamName())!=null)
				isPermited = responseBodyItems.get(index).isObject().get(ResParamNames.RES_ITEM_PERMISSINS.getParamName()).isObject().get(ResParamNames.RES_ITEM_SHARE_PERMIT.getParamName()).isBoolean().booleanValue();
		} catch (Exception e) {
			errorNotifier.showError(27,  e.getMessage());

		}
	
		return isPermited;
	}
	
	
	
	/**
	 * @param index - item index in the response
	 * @return JSONArray of sub items
	 */
	public   JSONArray getSubItems(int index){
		
		JSONArray subItems = null;
		
		try{
			if(responseBodyItems.get(index)!=null)
				if(responseBodyItems.get(index).isObject().get(ResParamNames.RES_SUB_ITEMS.getParamName())!=null)		
					subItems = responseBodyItems.get(index).isObject().get(ResParamNames.RES_SUB_ITEMS.getParamName()).isArray();
		} catch (Exception e) {
			errorNotifier.showError(28,  e.getMessage());

		}
		return subItems;
	}
	
	
	
	/**
	 * @param index - item index in the response
  	 * @return  if set, the name of the content item type, in case few types are mixed in the 
  	 * same response
	 */
	public  String getItemContentName(int index){
		
		String contentName = null;
		
		try{
			if(responseBodyItems.get(index)!=null)
				if(responseBodyItems.get(index).isObject().get(ResParamNames.RES_ITEM_CONTENT_NAME.getParamName())!=null)
					contentName = responseBodyItems.get(index).isObject().get(ResParamNames.RES_ITEM_CONTENT_NAME.getParamName()).isString().stringValue();
		} catch (Exception e) {
			errorNotifier.showError(29,  e.getMessage());

		}
		return contentName;
	}
	

}
